home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Mac Game Programming Gurus
/
TricksOfTheMacGameProgrammingGurus.iso
/
Book Chapters
/
07 - Mechanics - Environment
/
HexGridPlus
/
HexGrid.c
next >
Wrap
C/C++ Source or Header
|
1995-06-09
|
6KB
|
268 lines
// HexGrid
/*Size of the array*/
#define kArraySizeH 10
#define kArraySizeV 8
/* Pictures*/
PicHandle hexTile, altTile, thirdTile;
/* Define constants that match our hexes */
#define kHorizontalSpacing 32
#define kVerticalSpacing 26
/*HexToP: Convert grid coordinates to screen coordinates*/
Point HexToP(Point theHex, Point offset)
{
Point returnValue;
returnValue.v = kVerticalSpacing * theHex.v;
if ( (theHex.v & 1) == 0 )
returnValue.h = kHorizontalSpacing * theHex.h;
else
returnValue.h = kHorizontalSpacing * theHex.h + kHorizontalSpacing / 2;
return returnValue;
}; /*HexToP*/
/*AddToPoint: Offset a point by h,v*/
Point AddToPoint(Point p, short h, short v)
{
Point returnValue;
returnValue.h = p.h + h;
returnValue.v = p.v + v;
return returnValue;
};
/*MakePoint: Like SetPt but a function*/
Point MakePoint(short h, short v)
{
Point returnValue;
returnValue.h = h;
returnValue.v = v;
return returnValue;
};
/*GetNeighbor: Get a specified neighbor hex to a hex*/
Point GetNeighbor(Point source, short direction)
{
Point returnValue;
/*Direction 0 is to the right, then clockwise*/
if ( (source.v & 1) == 0 )
switch ( direction )
{
case 0:
returnValue = MakePoint(source.h + 1, source.v); break;
case 1:
returnValue = MakePoint(source.h, source.v + 1); break;
case 2:
returnValue = MakePoint(source.h - 1, source.v + 1); break;
case 3:
returnValue = MakePoint(source.h - 1, source.v); break;
case 4:
returnValue = MakePoint(source.h - 1, source.v - 1); break;
case 5:
returnValue = MakePoint(source.h, source.v - 1); break;
default:
SysBeep(1);
}/*case*/
else
switch ( direction )
{
case 0:
returnValue = MakePoint(source.h + 1, source.v); break;
case 1:
returnValue = MakePoint(source.h + 1, source.v + 1); break;
case 2:
returnValue = MakePoint(source.h, source.v + 1); break;
case 3:
returnValue = MakePoint(source.h - 1, source.v); break;
case 4:
returnValue = MakePoint(source.h, source.v - 1); break;
case 5:
returnValue = MakePoint(source.h + 1, source.v - 1); break;
default:
SysBeep(1);
};/*case*/
return returnValue;
}; /*GetNeighbor*/
/*Dist: Calculate the squared distance between two points*/
long Dist(Point p1, Point p2)
{
return (p1.h - p2.h) * (p1.h - p2.h) + (p1.v - p2.v) * (p1.v - p2.v);
};
/*PToHex: For a point in screen coordinates, find the hex it is located in*/
Point PToHex(Point thePoint, Point offset)
{
Point theHex;
Point p1, p2, p3;
Point h1, h2, h3;
long d1, d2, d3; /*integer?*/
Rect junkr; /*debug*/
Point tempPoint;
/*Find the hex in which "top rectangle" thePoint is located - not necessarily inside the hex*/
theHex.v = (thePoint.v - offset.v) / kVerticalSpacing;
if ( (theHex.v & 1) == 0 )
theHex.h = (thePoint.h - offset.h) / kHorizontalSpacing;
else
theHex.h = (thePoint.h - kHorizontalSpacing / 2 - offset.h) / kHorizontalSpacing;
/*Find the three hexes that are closest to thePoint*/
h1 = theHex; /*The lower hex*/
h2 = GetNeighbor(theHex, 4); /*The upper-left hex*/
h3 = GetNeighbor(theHex, 5); /*The upper-right hex*/
/*Get the center of each hex*/
p1 = AddToPoint(HexToP(h1, offset), kHorizontalSpacing / 2, kVerticalSpacing / 2);
p2 = AddToPoint(HexToP(h2, offset), kHorizontalSpacing / 2, kVerticalSpacing / 2);
p3 = AddToPoint(HexToP(h3, offset), kHorizontalSpacing / 2, kVerticalSpacing / 2);
/* The following plot the centers and the rectangle in which the point is located */
/* It is here for debugging and demo purposes - remove if you use this in a real program! */
MoveTo(p1.h, p1.v);
Line(0, 0);
MoveTo(p2.h, p2.v);
Line(0, 0);
MoveTo(p3.h, p3.v);
Line(0, 0);
tempPoint = HexToP(theHex, offset);
junkr.left = tempPoint.h;
junkr.top = tempPoint.v;
tempPoint = AddToPoint(HexToP(theHex, offset), kHorizontalSpacing, kVerticalSpacing);
junkr.right = tempPoint.h;
junkr.bottom = tempPoint.v;
FrameRect(&junkr);
/*Calculate the (squared) distance from thePoint to each hex center*/
d1 = Dist(p1, thePoint);
d2 = Dist(p2, thePoint);
d3 = Dist(p3, thePoint);
/*Pick the nearest hex!*/
if ( d1 < d2 )
if ( d3 < d1 ) /*not d2*/
/*d3*/
return h3;
else
/*d1*/
return h1;
else if ( d2 < d3 ) /*not d1*/
/*d2*/
return h2;
else
/*d3*/
return h3;
}; /*PToHex*/
/* Draw a tile */
void DrawHexTile(short h, short v, PicHandle hexTile)
{
Rect tileRectangle;
/* Use the picture frame */
tileRectangle = hexTile[0]->picFrame;
/* Move it to 0,0 */
OffsetRect(&tileRectangle, -tileRectangle.left, -tileRectangle.top);
/* Offset to the proper position */
/* For every other line, offset a bit extra */
if ( (v & 1) == 0 )
OffsetRect(&tileRectangle, kHorizontalSpacing * h, kVerticalSpacing * v);
else
OffsetRect(&tileRectangle, kHorizontalSpacing * h + kHorizontalSpacing / 2, kVerticalSpacing * v);
/* Draw it */
DrawPicture(hexTile, &tileRectangle);
}; /*DrawHexTile*/
/* Standard inits */
void InitToolbox()
{
InitGraf(&qd.thePort);
InitFonts ();
FlushEvents(everyEvent, 0);
InitWindows ();
InitMenus ();
TEInit ();
InitDialogs(nil);
InitCursor ();
};
/****************** Main program ******************/
void main(void)
{
WindowPtr myWindow;
Rect windowRectangle;
short h, v;
Point where; /*debug*/
short direction;
Point neighbor;
InitToolbox();
/*Set up the window*/
SetRect(&windowRectangle, 50, 50, 50 + kArraySizeH * kHorizontalSpacing + kHorizontalSpacing / 2, 50 + kArraySizeV * kVerticalSpacing + kVerticalSpacing / 3);
myWindow = NewCWindow(nil, &windowRectangle, "\pHex grid demo", true, 0, (WindowPtr)-1L, false, 0);
SetPort(myWindow);
/*Load the picture*/
hexTile = GetPicture(128); /*PICT resource #128.*/
altTile = GetPicture(129);
thirdTile = GetPicture(130);
/*Draw all tiles!*/
for ( h = 0 ; h <= kArraySizeH - 1 ; h++)
for ( v = 0 ; v <= kArraySizeV - 1 ; v++)
DrawHexTile(h, v, hexTile);
while ( ! Button () )
;
/*Demonstrate PToHex by drawing the hex in which the mouse is*/
GetMouse(&where);
where = PToHex(where, MakePoint(0, 0));
while ( Button () )
;
DrawHexTile(where.h, where.v, altTile);
/*Demonstrate GetNeighbor by drawing the neighbors as well*/
for ( direction = 0 ; direction <= 5 ; direction++)
{
neighbor = GetNeighbor(where, direction);
DrawHexTile(neighbor.h, neighbor.v, thirdTile);
};
while ( ! Button () )
;
} /*TextGrid*/